package com.zfzs.post.modules.agent.service.impl;

import com.alibaba.fastjson.JSON;
import com.zfzs.post.model.vo.WithdrawListVO;
import com.zfzs.post.modules.agent.domain.WithdrawOrder;
import com.zfzs.post.modules.agent.repository.WithdrawOrderRepository;
import com.zfzs.post.modules.agent.service.WithdrawOrderService;
import com.zfzs.post.modules.agent.service.dto.WithdrawOrderQueryCriteria;
import com.zfzs.post.modules.agent.service.mapper.WithdrawOrderMapper;
import com.zfzs.post.utils.PageUtil;
import com.zfzs.post.utils.QueryHelp;
import com.zfzs.post.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

/**
 * @author ck
 * @date 2019-10-18
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class WithdrawOrderServiceImpl implements WithdrawOrderService {

    @Autowired
    private WithdrawOrderRepository withdrawOrderRepository;

    @Autowired
    private WithdrawOrderMapper withdrawOrderMapper;

    @Override
    public Object queryAll(WithdrawOrderQueryCriteria criteria, Pageable pageable) {
        Page<WithdrawOrder> page = withdrawOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(withdrawOrderMapper::toDto));
    }

    @Override
    public Object queryAll(WithdrawOrderQueryCriteria criteria) {
        return withdrawOrderMapper.toDto(withdrawOrderRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    public WithdrawOrder findById(Integer id) {
        Optional<WithdrawOrder> withdrawOrder = withdrawOrderRepository.findById(id);
        return withdrawOrder.get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WithdrawOrder create(WithdrawOrder resources) {
        //生成订单号
        String orderNo = StringUtils.getDateString(5);
        resources.setFeeAmount(new BigDecimal(0));
        resources.setStatus(0);
        resources.setOrderNo(orderNo);
        resources.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        resources.setCreateDate(new Timestamp(System.currentTimeMillis()));
        resources.setCreateTime(new Timestamp(System.currentTimeMillis()));
        return withdrawOrderRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(WithdrawOrder resources) {
        Optional<WithdrawOrder> optionalWithdrawOrder = withdrawOrderRepository.findById(resources.getWithdrawId());
        WithdrawOrder withdrawOrder = optionalWithdrawOrder.get();
        withdrawOrder.copy(resources);
        withdrawOrderRepository.save(withdrawOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Integer id) {
        withdrawOrderRepository.deleteById(id);
    }

    @Override
    public List<WithdrawListVO> withdrawList(Long agentId) {
        List<Map<Map, Object>> list = withdrawOrderRepository.withdrawList(agentId);
        List<WithdrawListVO> collect = list.stream()
                .map(e -> {
                    WithdrawListVO agent = JSON.parseObject(JSON.toJSONString(e), WithdrawListVO.class);
                    return agent;
                }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public Page<WithdrawOrder> findOrderPage(WithdrawOrderQueryCriteria criteria, Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size);

        Specification specification = (root, query, cb) -> {

            if (criteria.getStatus() != null) {
                query.where(cb.equal(root.get("status"), criteria.getStatus()));
            }

            if (criteria.getChannelId() != null) {
                query.where(cb.equal(root.get("channelId"), criteria.getChannelId()));
            }


            if (criteria.getAgentIds() != null && !criteria.getAgentIds().isEmpty()) {
                query.where(root.get("agentId").in(criteria.getAgentIds()));
            }

            if (StringUtils.isNotBlank(criteria.getStartDate()) && StringUtils.isNotBlank(criteria.getEndDate())) {
                query.where(cb.between(root.get("createTime").as(String.class),criteria.getStartDate(),criteria.getEndDate()));
            }


            query.orderBy(cb.desc(root.get("createTime")));
            return query.getRestriction();
        };

        return withdrawOrderRepository.findAll(specification, pageable);
    }
}